package com.ziki.test.socket;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import com.ziki.test.socket.thread.DataRecvThread;
import com.ziki.test.socket.thread.DataSendThread;
import com.ziki.test.socket.util.Log;
import com.ziki.test.socket.util.PubFun;

public class MySocket {
    /** 协议类型(0:移动,1:联通,2:电信,3:网通,4:SMPP) */
    public int protocol;

    public int socketNumber;
    /** 0：收发，1：发送 2：接收 */
    public int loginType; // 0：收发，1：发送 2：接收
    /** socket是否连接成功 */
    public boolean socketFlag = false; // socket是否连接成功
    /** login是否连接成功 */
    public boolean loginFlag = false; // login是否连接成功
    /** 最后一次login时间 */
    public java.util.Date LastloginTime; // 最后一次login时间
    /** 最后一次resp时间 */
    public java.util.Date lastRespTime = new java.util.Date(); // 最后一次resp时间

    public int notRespCount = 0;

    public DataInputStream dis;

    public DataOutputStream dos;

    private String serverIP;

    private int serverPort;

    private Socket socket;
    /** 发送线程socketOutThread */
    DataSendThread socketOutThread = null;
    /** 接收线程socketInThread */
    DataRecvThread socketInThread = null;

    public MySocket(String serverIP, int serverPort, int protocol, int loginType, int socketNumber) {
        this.serverIP = serverIP;
        this.serverPort = serverPort;
        this.protocol = protocol;
        this.loginType = loginType;
        this.socketNumber = socketNumber;
    }

    public MySocket(Socket oSocket, int protocol, int loginType, int socketNumber) {
        this.socket = oSocket;
        this.protocol = protocol;
        this.loginType = loginType;
        this.socketNumber = socketNumber;
        try {
            this.socket.setSendBufferSize(888888888);
            this.socket.setReceiveBufferSize(888888888);
            this.socket.setSoTimeout(30000);
            dos = new DataOutputStream(new BufferedOutputStream(this.socket.getOutputStream()));
            dis = new DataInputStream(new BufferedInputStream(this.socket.getInputStream()));
        } catch (Exception ex) {
            Log.write2Log(3, "系统信息", "接收socket异常，原因：" + ex.getMessage());
        }
        socketFlag = true;
        notRespCount = 0;
    }

    /**
     * 连接服务器，设置IP,PORT以及输入输出流
     */
    public synchronized void linkServer() {
        if (socketFlag) {
            return;
        }
        try {
            Log.write2Log(3, "系统信息", "连接至服务器IP：" + serverIP + "，端口号：" + serverPort + "，开始");
            socket = new Socket(serverIP, serverPort);
            socket.setSendBufferSize(888888888);
            socket.setReceiveBufferSize(888888888);
            socket.setSoTimeout(30000);
            dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
            dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            socketFlag = true;
            notRespCount = 0;
            Log.write2Log(3, "系统信息", "连接至服务器IP：" + serverIP + "，端口号：" + serverPort + "，成功");

        } catch (Exception e) {
            Log.write2Log(3, "系统信息", "连接至服务器IP：" + serverIP + "，端口号：" + serverPort + "，失败，原因：" + e.getMessage());
            socketFlag = false;
            loginFlag = false;
        }
    }

    public synchronized void unLink() {
        if (socket == null || !socketFlag) {
            return;
        }
        try {
            dis.close();
            dos.close();
            socket.close();
        } catch (Exception e) {
        }
        notRespCount = 0;
        LastloginTime = null;
        socketFlag = false;
        loginFlag = false;
    }

    /**
     * 发送二进制数据
     * 
     * @param data
     * @return
     */
    public boolean sendData(byte[] data) {
        boolean ret = false;
        if (socket == null || !socketFlag) {
            this.linkServer();
            return false;
        }
        try {
            dos.write(data);
            dos.flush();
            ret = true;
        } catch (IOException ioe) {
            ioe.printStackTrace();
            Log.write2Log(3, "系统信息", "发送数据，IO异常，断开Socket连接，原因：" + ioe.getMessage());
            this.unLink();
            ret = false;
        }
        return ret;
    }

    /**
     * 接收二进制数据<br>
     * dataSize > 4 && dataSize < 1024
     * 
     * @return
     */
    public byte[] recvData() {
        byte[] data = null;
        int dataSize = 0;
        if (socket == null || !socketFlag) {
            return data;
        }
        try {
            dataSize = dis.readInt();
            if (dataSize > 4 && dataSize < 1024) {
                int dataTotalSizeToRead = dataSize - 4;
                data = new byte[dataSize];
                System.arraycopy(PubFun.toByteArray(dataSize), 0, data, 0, 4);
                dis.read(data, 4, dataTotalSizeToRead);
            }
        } catch (java.io.IOException ioe) {
            ioe.printStackTrace();
            Log.write2Log(3, "系统信息", "接收数据，IO异常，断开Socket连接，原因：" + ioe.getMessage());

            this.unLink();
            data = null;
            return data;
        }

        return data;
    }

    /**
     * 发送数据线程进行发送数据<br>
     * 启动发送线程,发送submitVector队列数据,加入submitBuffer队列
     */
    public void startSend() {
        socketOutThread = new DataSendThread(this);
    }

    /**
     * 接收数据线程进行接收数据 SUBMIT状态命令,去除submitBuffer中的记录,加入到submitRespVector中<br>
     * DELIVER命令,生成deliverData数据,加入deliverVector,发送接收状态包
     */
    public void startRecv() {
        socketInThread = new DataRecvThread(this);
    }

    public void stopRun() {
        if (socketOutThread != null) {
            socketOutThread.stopRun();
        }
        if (socketInThread != null) {
            socketInThread.stopRun();
        }
        this.unLink();
    }
}
